package cn.stylefeng.guns.sys.core.upay.response;


import cn.stylefeng.guns.sys.core.upay.enums.BizType;
import cn.stylefeng.guns.sys.core.upay.exception.UpayException;
import cn.stylefeng.guns.sys.core.upay.utils.CipherUtils;
import cn.stylefeng.guns.sys.core.upay.utils.DateUtils;
import cn.stylefeng.guns.sys.core.upay.utils.StringUtils;
import cn.stylefeng.guns.sys.core.upay.utils.Utils;

import java.util.Map;
import java.util.TreeMap;

/**
 * 公共部分请求数据格式
 * Created by jcouyang@chinaums.com on 2017/7/17.
 */
public class UpayRequest extends Validator{
    protected String merchant_id;
    protected String terminal_id;
    protected String operator_id;
    protected String device_id;
    protected String request_id;
    protected String term_request_id;
    protected String timestamp = DateUtils.formatNow(DateUtils.YYYY_MM_DD_HH_MM_SS);
    protected String biz_channel;
    protected String biz_type;
    protected String biz_content;
    protected String notify_url;
    protected String version;
    protected String app_info;
    protected String sign;
    // 默认走RSA
    protected String sign_type="md5";
    protected String sign_format = "pkcs8";

    public UpayRequest() {
        this.request_id = produceRequestId();
        this.term_request_id = produceRequestId();
    }

    @Override
    public boolean validate() {

        if (StringUtils.isEmpty(merchant_id)) {
            throw new RuntimeException("商户号[merchant_id]不可为空");
        }

        if (StringUtils.isEmpty(merchant_id)) {
            throw new RuntimeException("商户号[merchant_id]不可为空");
        }

        if (StringUtils.isEmpty(merchant_id)) {
            throw new RuntimeException("商户代码[merchant_id]不可为空");
        }

        if (StringUtils.isEmpty(terminal_id)) {
            throw new RuntimeException("终端编号[terminal_id]不可为空");
        }

        if (StringUtils.isEmpty(request_id)) {
            throw new RuntimeException("交易请求号[request_id]不可为空");
        }

        if (StringUtils.isEmpty(timestamp)) {
            throw new RuntimeException("交易当前时间戳[timestamp]不可为空");
        }

        if (StringUtils.isEmpty(biz_channel)) {
            throw new RuntimeException("交易渠道[biz_channel]不可为空");
        }

        if (StringUtils.isEmpty(biz_type)) {
            throw new RuntimeException("交易类型[biz_type]不可为空");
        }

        if (StringUtils.isEmpty(app_info)) {
            throw new RuntimeException("应用程序信息[app_info]不可为空");
        }

        if (StringUtils.isEmpty(sign)) {
            throw new RuntimeException("签名[sign]不可为空");
        }

        if (StringUtils.isEmpty(sign_type)) {
            throw new RuntimeException("签名算法[sign_type]不可为空");
        }

        return true;
    }

    /**
     * 获取发送的数据，需要在所有的参数设置完成后再调用该方法
     * @return
     */
    public Map<String, String> getSendData(String key) throws UpayException {
        try {
            // 对象转为Map对象
            TreeMap<String, String> map = (TreeMap<String, String>) Utils.convertBean(this, true);

            // OTA不需要签名
            if (BizType.UMSZJ_TRADE_OTAINIT.getEn().equalsIgnoreCase(biz_type)) {
                map.put("sign", "1234");
            }
            else {
                map.remove("sign");
                String signType   = map.remove("sign_type");
                String signFormat = map.remove("sign_format");

                StringBuffer sbtr = new StringBuffer();
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    sbtr.append(entry.getKey());
                    sbtr.append("=");
                    sbtr.append(entry.getValue());
                    sbtr.append("&");
                }

                String signStr = sbtr.substring(0, sbtr.length() - 1);
                String sign;
                if ("md5".equalsIgnoreCase(signType)) {
                    signStr += "&key=" + key;

                    sign = CipherUtils.md5(signStr);
                    map.put("sign", sign);
                    map.put("sign_format", signFormat);
                    map.put("sign_type", signType);
                } else {
                    sign = CipherUtils.sign(signStr, key, "UTF-8");
                    map.put("sign", sign);
                    map.put("sign_format", signFormat);
                    map.put("sign_type", signType);
                }

                this.sign        = sign;
                this.sign_type   = signType;
                this.sign_format = signFormat;
            }

            if(validate()) {
                return map;
            }
            else {
                throw new UpayException("参数校验不通过");
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new UpayException(e);
        }

    }

    private String produceRequestId() {
        return DateUtils.formatNow(DateUtils.YYYYMMDDHHMMSS)+String.format("%06d", (int)(Math.random()*1000000));
    }

    public String getMerchant_id() {
        return merchant_id;
    }

    public void setMerchant_id(String merchant_id) {
        this.merchant_id = merchant_id;
    }

    public String getTerminal_id() {
        return terminal_id;
    }

    public void setTerminal_id(String terminal_id) {
        this.terminal_id = terminal_id;
    }

    public String getOperator_id() {
        return operator_id;
    }

    public void setOperator_id(String operator_id) {
        this.operator_id = operator_id;
    }

    public String getDevice_id() {
        return device_id;
    }

    public void setDevice_id(String device_id) {
        this.device_id = device_id;
    }

    public String getRequest_id() {
        return request_id;
    }

    public void setRequest_id(String request_id) {
        this.request_id = request_id;
    }

    public String getTerm_request_id() {
        return term_request_id;
    }

    public void setTerm_request_id(String term_request_id) {
        this.term_request_id = term_request_id;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public String getBiz_channel() {
        return biz_channel;
    }

    public void setBiz_channel(String biz_channel) {
        this.biz_channel = biz_channel;
    }

    public String getBiz_type() {
        return biz_type;
    }

    public void setBiz_type(String biz_type) {
        this.biz_type = biz_type;
    }

    /**
     * 这里需要把返回值设置为String类型，否则在对象转Map的时候会报错
     * 如果要转对对象，可以去到String以后转换为T类型的对象
     * @return bizContent
     */
    public String getBiz_content() {
        return biz_content.toString();
    }

    public void setBiz_content(String biz_content) {
        this.biz_content = biz_content;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getApp_info() {
        return app_info;
    }

    public void setApp_info(String app_info) {
        this.app_info = app_info;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getSign_type() {
        return sign_type;
    }

    public void setSign_type(String sign_type) {
        this.sign_type = sign_type;
    }

    public String getSign_format() {
        return sign_format;
    }

    public void setSign_format(String sign_format) {
        this.sign_format = sign_format;
    }
}
